package toutiao

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"net/url"
	"strings"
	"time"

	"publish/pub-lib/baijia"
	"publish/pub-lib/utils"
	"github.com/astaxie/beego"
)

func (t *ToutiaoApi) PublishArticle(cat string,tag string,feedArticle baijia.FeedArticle) (error) {

	article := TtArticle{Title: feedArticle.Title}
	article.ImageCovers = []CoverImage{}
	imageIndex := 0
	for _, feed := range feedArticle.Feed {
		if feed.Type == "image" {
			res, err := t.UploadImageByUrl(feed.Data)
			if err != nil {
				beego.Error(err.Error())
				return errors.New("图片上传失败，请检查账号是否可用")
			}
			article.Content += fmt.Sprintf(`<p><img src="%s"/></p>`, res.Url)
			urlSplits := strings.Split(res.Url, "/")
			uri := urlSplits[len(urlSplits)-1]
			article.ImageCovers = append(article.ImageCovers, CoverImage{Id: imageIndex, Url: res.Url, Uri: "pgc-image/"+uri, OriginUri: "pgc-image/"+uri, ThumbHeight: 450, ThumbWidth: 640})
			imageIndex++
		}

		if feed.Type == "text" {
			article.Content += fmt.Sprintf(`<p>%s</p>`, feed.Data)
		}
	}
	if len(article.ImageCovers) > 3 {
		article.ImageCovers = article.ImageCovers[:3]
	} else if len(article.ImageCovers) > 1 {
		article.ImageCovers = article.ImageCovers[:1]
	}
	_,err := t.publish(article)
	return err
}



func (t *ToutiaoApi) PublishGallery(cat string,tag string,feeds baijia.FeedArticle) (error) {

	gallery := TtGallery{GalleryData: []KV{}, GalleryInfo: []KV{}}
	gallery.Title = feeds.Title
	gallery.Content = "{!-- PGC_GALLERY:"
	gc := GalleryContent{List: []Gallery{}}
	imageIndex := 0
	for _, feed := range feeds.Feed {
		if feed.Type == "image" {

			req := utils.Get(feed.Data)
			byteArray, err := req.Bytes()
			if err != nil {
				return err
			}
			res, err := t.GralleryUploadImageByFile(ioutil.NopCloser(bytes.NewBuffer(byteArray)), "gallery_imgae")
			if err != nil {
				fmt.Println("UploadImageByUrl|", err.Error())
				continue
			}
			galleryId := getGalleryId()

			gc.List = append(gc.List, Gallery{Url: res.Url, Uri: res.Original, IcUri: "", Product: make(map[string]string), Desc: feed.Desc, WebUri: res.Original, UrlPattern: "{{image_domain}}", GalleryId: galleryId})

			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][url]`, galleryId), res.Url})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][uri]`, galleryId), res.Original})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][ic_uri]`, galleryId), ""})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][desc]`, galleryId), feed.Desc})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][web_uri]`, galleryId), res.Original})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][url_pattern]`, galleryId), "{{image_domain}}"})
			gallery.GalleryData = append(gallery.GalleryData, KV{fmt.Sprintf(`gallery_data[%d][gallery_id]`, galleryId), fmt.Sprintf("%d", galleryId)})

			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][url]`, imageIndex), res.Url})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][uri]`, imageIndex), res.Original})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][ic_uri]`, imageIndex), ""})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][desc]`, imageIndex), feed.Desc})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][web_uri]`, imageIndex), res.Original})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][url_pattern]`, imageIndex), "{{image_domain}}"})
			gallery.GalleryInfo = append(gallery.GalleryInfo, KV{fmt.Sprintf(`gallery_info[%d][gallery_id]`, imageIndex), fmt.Sprintf("%d", galleryId)})

			imageIndex++
		}
	}

	gcBytes, err := json.Marshal(gc)
	if err != nil {
		return err
	}
	gallery.Content += string(gcBytes)
	gallery.Content += ` --}` //非常非常重要的空格
	_,err = t.publishGallery(gallery)
	return err
}


func (p *ToutiaoApi) PublishVideo(cat string,tag string,feeds baijia.FeedArticle) error {
	videoBytes := []byte{}
	var err error
	desc := ""
	for _, feed := range feeds.Feed {
		if feed.Type == "video" {
			req := utils.Get(feed.Data)
			videoBytes, err = req.Bytes()
			utils.ChangeMd5_Bytes(videoBytes)
			if err != nil {
				return errors.New("视频请求失败:" + err.Error())
			}
			desc = feed.Desc
		}
	}

	return p.publishVideoLogic(p.mid, p.username, feeds.Title, desc, "video_funny", "美女", videoBytes, "video.mp4", int64(len(videoBytes)))
}

func (t *ToutiaoApi) UrlPublish(cat string,parseUrl string) (*PostArticleResponse, error) {
	ul := `http://127.0.0.1:3333/article/feed?url=%s`
	req := utils.Get(fmt.Sprintf(ul, url.QueryEscape(parseUrl)))
	feedArticle := baijia.FeedArticle{}
	err := req.ToJSON(&feedArticle)
	if err != nil {
		return nil, err
	}

	return nil,t.PublishArticle(cat,"美女",feedArticle)
}



func (t *ToutiaoApi) publishVideoLogic(mid int64, username string, title string, desc string, tag string, label string, video []byte, videoname string, videoSize int64) error {
	md5Ctx := md5.New()
	md5Ctx.Write(video)
	cipherStr := md5Ctx.Sum(nil)
	videomMd5 := hex.EncodeToString(cipherStr)

	err := t.uploadVideoMd5(videomMd5)
	if err != nil {
		beego.Error("上传视频MD5 【失败】")
		return err
	}
	beego.Info("上传视频MD5 【成功】")

	api, err := t.getUploadApi()

	if err != nil {
		beego.Error("获取上传视频API 【失败】")
		return err
	}
	beego.Info("获取上传视频API 【成功】")

	plog := PreUploadLog{E: "开始上传", Code: 0, RefId: api.UploadId, At: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), Timestamp: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), F: videoname, Url: "https://mp.toutiao.com/profile_v2/pure-video", Ubs: 0, Fs: videoSize, Ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36", Cookie: t.ck, LogData: []UploadResponse{}, Username: username, Mid: mid}
	err = t.preUploadVideo(api.UploadId, plog)
	if err != nil {
		beego.Error("准备上传视频 【失败】")
		return err
	}
	beego.Info("准备上传视频 【成功】")

	beego.Info("正在上传视频中...")
	uploadresponse, err := t.uploadVideo(videoname, api, ioutil.NopCloser(bytes.NewReader(video)))
	if err != nil {
		beego.Error("上传视频 【失败】")
		return err
	}
	beego.Info("上传视频 【成功】")

	logidAndVia := ""
	text, err := json.Marshal(uploadresponse)
	if err != nil {
		return err
	}

	elog := EndUploadLog{E: "文件上传成功", Ts: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), Te: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), RefId: api.UploadId, At: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), Timestamp: int64(math.Floor(float64(time.Now().UnixNano() / 1e6))), F: videoname, Url: "https://mp.toutiao.com/profile_v2/pure-video", Ubs: 0, Fs: videoSize, LogId: &logidAndVia, Via: &logidAndVia, Text: string(text), Ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36", Cookie: t.ck, LogData: []UploadResponse{uploadresponse}, Username: username, Mid: mid}
	err = t.endUploadVideo(api.UploadId, elog)
	if err != nil {
		beego.Error("完成上传视频 【失败】")
		return err
	}
	beego.Info("完成上传视频 【成功】")

	time.Sleep(2000 * time.Millisecond)
	maxreCount := 5
	images := ImagesResponse{}
	for {
		if maxreCount <= 0 {
			return errors.New(`获取视频封面失败`)
		}
		time.Sleep(1000 * time.Millisecond)
		images, err = t.getVideoImage(api.UploadId)
		if err != nil {
			maxreCount--
			beego.Error("自动获取上传视频封面 【失败】:", err.Error())
			continue
		}
		beego.Info("自动获取上传视频封面 【成功】")

		if len(images.Data) <= 0 {
			beego.Info("获取视频封面失败:" + images.Message)
			maxreCount--
			continue
		}
		break
	}

	err = t.reportVideoThumb(api.UploadId, images.Data[0].Uri)
	if err != nil {
		beego.Error("确定视频封面 【失败】")
		return err
	}
	beego.Info("确定视频封面 【成功】")

	contentF := `<p>{!-- PGC_VIDEO:{"sp":"toutiao","vid":"%s","vu":"%s","thumb_url":"%s","src_thumb_uri":"%s","vname":"%s"} --}</p>`
	content := fmt.Sprintf(contentF, api.UploadId, api.UploadId, images.Data[0].Uri, images.Data[0].SrcUri, videoname)
	err = t.publishVideo(PubVideo{Title: title, Desc: desc, Tag: tag, Content: content, ArticleLabel: label})
	if err != nil {
		beego.Error("发表视频 【失败】")
		return err
	}
	beego.Info("发表视频 【成功】")
	return nil
}
